﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Globalization;
using System.Xml;

namespace Nuane.Posterous
{
	/// <summary>
	/// Defines known types of posterous-hosted media files.
	/// </summary>
	public enum PosterousMediumType
	{
		/// <summary>
		/// Image.
		/// </summary>
		Image = 1,

		/// <summary>
		/// Audio.
		/// </summary>
		Audio = 2,

		/// <summary>
		/// Video.
		/// </summary>
		Video = 3,
	}

	/// <summary>
	/// Posterous media info.
	/// </summary>
	public class PosterousMedium
	{
		/// <summary>
		/// Gets the medium type.
		/// </summary>
		/// <value>Medium type.</value>
		public PosterousMediumType Type { get; protected set; }

		/// <summary>
		/// Gets a link to the image, audio or video.
		/// </summary>
		/// <value>Link to medium.</value>
		public Uri Uri { get; protected set; }

		/// <summary>
		/// Gets the file length of the image, audio or video.
		/// </summary>
		/// <value>File length of the video.</value>
		public long FileLength { get; protected set; }

	}

	/// <summary>
	/// Posterous image info.
	/// </summary>
	public class PosterousImage : PosterousMedium
	{
		//<media>
		//  <type>image</type>
		//  <medium>  
		//    <url>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/IMG_0477.scaled500.jpg</url>  
		//    <filesize>47</filesize>  
		//    <height>333</height>  
		//    <width>500</width>  
		//  </medium>  
		//  <thumb> 
		//    <url>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/IMG_0477.thumb.jpg</url>  
		//    <filesize>5</filesize>  
		//    <height>36</height>  
		//    <width>36</width>  
		//  </thumb>
		//</media>  

		/// <summary>
		/// Gets image width.
		/// </summary>
		/// <value>Image width.</value>
		public int Width { get; private set; }

		/// <summary>
		/// Gets image height.
		/// </summary>
		/// <value>Image height.</value>
		public int Height { get; private set; }

		/// <summary>
		/// Gets a link to image thumbnail.
		/// </summary>
		/// <value>Link to image thumbnail.</value>
		public Uri ThumbnailUri { get; private set; }

		/// <summary>
		/// Gets the file length of image thumbnail.
		/// </summary>
		/// <value>File length of image thumbnail.</value>
		public long ThumbnailFileLength { get; private set; }

		/// <summary>
		/// Gets image thumbnail width.
		/// </summary>
		/// <value>Image thumbnail width.</value>
		public int ThumbnailWidth { get; private set; }

		/// <summary>
		/// Gets image thumbnail height.
		/// </summary>
		/// <value>Image thumbnail height.</value>
		public int ThumbnailHeight { get; private set; }

		internal PosterousImage(XmlNode media)
		{
			Type = PosterousMediumType.Image;

			if (media.Name != "media")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			string type = Helper.GetChildElementValue(media, "type");
			if (type != "image")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			XmlNode medium = media["medium"];
			if (medium == null)
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			Uri = Helper.ToUri(Helper.GetChildElementValue(medium, "url"));
			FileLength = Helper.ToInt32(Helper.GetChildElementValue(medium, "filesize"));
			Width = Helper.ToInt32(Helper.GetChildElementValue(medium, "width"));
			Height = Helper.ToInt32(Helper.GetChildElementValue(medium, "height"));

			XmlNode thumb = media["thumb"];
			if (thumb != null)
			{
				ThumbnailUri = Helper.ToUri(Helper.GetChildElementValue(thumb, "url"));
				ThumbnailFileLength = Helper.ToInt32(Helper.GetChildElementValue(thumb, "filesize"));
				ThumbnailWidth = Helper.ToInt32(Helper.GetChildElementValue(thumb, "width"));
				ThumbnailHeight = Helper.ToInt32(Helper.GetChildElementValue(thumb, "height"));
			}
		}
	}

	/// <summary>
	/// Posterous audio info.
	/// </summary>
	public class PosterousAudio : PosterousMedium
	{
		//<media>  
		//  <type>audio</type>  
		//  <url>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/sheila.mp3</url>  
		//  <filesize>10116</filesize>  
		//  <artist>Smashing Pumpkins</artist>  
		//  <album>Adore</album>  
		//  <song>To Sheila</song>  
		//</media>

		/// <summary>
		/// Gets the audio artist.
		/// </summary>
		/// <value>Audio artist.</value>
		public string Artist { get; private set; }

		/// <summary>
		/// Gets the audio album.
		/// </summary>
		/// <value>Audio album.</value>
		public string Album { get; private set; }

		/// <summary>
		/// Gets tha audio song.
		/// </summary>
		/// <value>Audio song.</value>
		public string Song { get; private set; }

		internal PosterousAudio(XmlNode media)
		{
			if (media.Name != "media")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			string type = Helper.GetChildElementValue(media, "type");
			if (type != "audio")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			Uri = Helper.ToUri(Helper.GetChildElementValue(media, "url"));
			FileLength = Helper.ToInt32(Helper.GetChildElementValue(media, "filesize"));
			Artist = Helper.GetChildElementValue(media, "artist", false);
			Album = Helper.GetChildElementValue(media, "album", false);
			Song = Helper.GetChildElementValue(media, "song", false);
		}
	}

	/// <summary>
	/// Posterous video info.
	/// </summary>
	public class PosterousVideo : PosterousMedium
	{
		//<media>  
		//  <type>video</type>  
		//  <url>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/movie.avi</url>  
		//  <filesize>6537</filesize>  
		//  <thumb>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/movie.png</thumb>  
		//  <flv>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/movie.flv</flv>  
		//  <mp4>http://posterous.com/getfile/files.posterous.com/sachin/DIptatiCkiv/movie.mp4</mp4>  
		//</media>

		/// <summary>
		/// Gets a link to a thumbnail image.
		/// </summary>
		/// <value>Link to thumbnail image.</value>
		public Uri ThumbnailUri { get; private set; }

		/// <summary>
		/// Gets a link to the video in FLV format.
		/// </summary>
		/// <value>Link to the video in FLV format.</value>
		public Uri FlvUri { get; private set; }

		/// <summary>
		/// Gets a link to the video in MPEG-4 format.
		/// </summary>
		/// <value>Link to the video in MPEG-4 format.</value>
		public Uri Mpeg4Uri { get; private set; }

		internal PosterousVideo(XmlNode media)
		{
			if (media.Name != "media")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			string type = Helper.GetChildElementValue(media, "type");
			if (type != "video")
				throw new PosterousException("Invalid response.", PosterousExceptionStatus.ServerProtocolViolation);

			Uri = Helper.ToUri(Helper.GetChildElementValue(media, "url"));
			FileLength = Helper.ToInt32(Helper.GetChildElementValue(media, "filesize"));
			ThumbnailUri = Helper.ToUri(Helper.GetChildElementValue(media, "thumb"));
			FlvUri = Helper.ToUri(Helper.GetChildElementValue(media, "flv", false), true);
			Mpeg4Uri = Helper.ToUri(Helper.GetChildElementValue(media, "mp4", false), true);
		}
	}
}

